import React, { Suspense } from 'react';
import { Layout ,Tabs,Dropdown,Menu,Icon ,message} from 'antd';
import DocumentTitle from 'react-document-title';
import { Route } from 'react-router-dom';
import router from 'umi/router';
import { connect } from 'dva';
import { ContainerQuery } from 'react-container-query';
import classNames from 'classnames';
import Media from 'react-media';

import Footer from './Footer';
import Header from './Header';
import Context from './MenuContext';
import SiderMenu from '@/components/SiderMenu';
import getPageTitle from '@/utils/getPageTitle';
import styles from './BasicLayout.less';
import PageLoading from '@/components/PageLoading';
import {title,platform_logo} from '../defaultSettings';
// lazy load SettingDrawer
const SettingDrawer = React.lazy(() => import('@/components/SettingDrawer'));
const { TabPane } = Tabs;
const { Content } = Layout;

const query = {
  'screen-xs': {
    maxWidth: 575,
  },
  'screen-sm': {
    minWidth: 576,
    maxWidth: 767,
  },
  'screen-md': {
    minWidth: 768,
    maxWidth: 991,
  },
  'screen-lg': {
    minWidth: 992,
    maxWidth: 1199,
  },
  'screen-xl': {
    minWidth: 1200,
    maxWidth: 1599,
  },
  'screen-xxl': {
    minWidth: 1600,
  },
};

class BasicLayout extends React.Component {
  getKeyToRouteData = (routes)=>{
    const routeMap = {};
    const getMap = data => {
      data.forEach(node => {
        if (node.routes && node.routes.length > 0) {
          getMap(node.routes);
        }else {
            routeMap[node.path] =node;
        }
      });
    };
    getMap(routes);
    return routeMap;
  }
  getMainPath = (routes,tabLists)=>{
    if(tabLists['/']){
      if(tabLists['/'].redirect){
        return tabLists['/'].redirect;
      }else{
        return tabLists['/'].path
      }
    }else{
      return '/exception/404'
    }

  }
  constructor(props) {
    super(props);
    const { hidenAntTabs ,menuData } = props;
    const { routes } = props.route;
    //console.log("routes==",routes);
    const tabLists = this.getKeyToRouteData(routes);
    let mainPath = this.getMainPath(routes,tabLists);
    let activeKey = '';//选中页面
    let tabList = [];
    if(tabLists[props.location.pathname]){ //如果存在访问页的路由
      if (!hidenAntTabs) { //如果不隐藏tab
        if(mainPath != '/exception/404'){ //如果路由里存在首页
          tabList.push({ tab: tabLists[mainPath].name, key: tabLists[mainPath].path, locale: tabLists[mainPath].locale, closable: false, content: tabLists[mainPath].component });//定义首页
        }else{
          message.warning('未发现首页路由！');
        }

        if (props.location.pathname != mainPath && props.location.pathname != '/')  { //如果首页不是/ 那么就再添加一个tablist ;其中 props.location.pathname为首页
          tabList.push({ tab: tabLists[props.location.pathname].name, key: tabLists[props.location.pathname].path, locale: tabLists[props.location.pathname].locale, closable: true, content: tabLists[props.location.pathname].component });
          activeKey=props.location.pathname;
        }else{
          activeKey=mainPath;
        }

      }else{
        activeKey = props.location.pathname;
      }
      this.state = {
        tabList:tabList, // tab页列表
        tabListKeys : tabList && tabList.length === 2 ? [mainPath,activeKey] : [mainPath], //已选中的路由key列表
        activeKey: activeKey, //选中的tab页
        searchObj :{activeKey :props.location.search}, //搜索对象 格式为map    {  路径key ：搜索条件}
        routeForKey:tabLists, // 根据每个路由的key 生成的map
        mainPath : mainPath,
      }
      router.push(activeKey+props.location.search)
    }else{
      window.location.href = "/exception/404"
    }

  }
  componentDidMount() {
    const {
      dispatch,
      route: { routes, path, authority },
    } = this.props;
    dispatch({
      type: 'user/fetch',
    });
    dispatch({
      type: 'setting/getSetting',
    });
    dispatch({
      type: 'menu/getMenuData',
      payload: { routes, path, authority },
    });
  }
  componentWillReceiveProps(nextProps) {
    const prevLocation = this.props.location.pathname;
    const nextLocation = nextProps.location.pathname;
    const nextSearch = nextProps.location.search;
    const { tabList, tabListKeys, routeForKey,searchObj } = this.state;


    if(prevLocation != nextLocation){

      if (routeForKey[nextLocation]){ //如果存在此路由
        searchObj[nextLocation] = nextSearch;
        if (tabListKeys.includes(nextLocation)) { //如果在顶部tab列表内
          this.setState({
            activeKey: nextLocation,
            searchObj: searchObj//搜索条件重置
          })
        } else {
          tabList.push({ tab: routeForKey[nextLocation].name, key: routeForKey[nextLocation].path, locale: routeForKey[nextLocation].locale, closable: true, content: routeForKey[nextLocation].component });
          this.setState({
            activeKey:nextLocation,
            tabListKeys : [...tabListKeys,nextLocation],
            tabList :tabList,
            searchObj :searchObj,
          })
        }
        router.push(nextLocation+nextSearch)
      }else{
        router.push('/exception/404')
      }
    }
  }
  getContext() {
    const { location, breadcrumbNameMap } = this.props;
    return {
      location,
      breadcrumbNameMap,
    };
  }
// 切换 tab页 router.push(key);
  onChange = key => {
    this.setState({ activeKey: key });
    const search = this.state.searchObj[key]?this.state.searchObj[key]:''
    router.push(key+search);
  };
  onEdit = (targetKey, action) => {

    if(this[action]){
      this[action](targetKey);
    }

  }
  removeAll = ()=>{
    const tabList = [], tabListKey = [] ,searchObj = {};
    const mainPath = this.state.mainPath;
    this.state.tabList.forEach((pane, i) => {
      if (pane.key === mainPath) {
        tabList.push(pane)
        tabListKey.push(pane.key)
        searchObj[mainPath] =this.state.searchObj[mainPath]
      }
    });
    this.setState({
      tabList:tabList,
      tabListKeys:tabListKey,
      searchObj:searchObj
    });
    router.push(mainPath+searchObj[mainPath]?mainPath:'');
  }
  removeOther = ()=>{
    const tabList = [], tabListKey = [] ,searchObj = {};
    const targetKey = this.state.activeKey;
    const mainPath = this.state.mainPath;
    this.state.tabList.forEach((pane, i) => {
      if (pane.key === targetKey || pane.key === mainPath) {
        tabList.push(pane)
        tabListKey.push(pane.key)
        searchObj[targetKey] =this.state.searchObj[targetKey]
      }
    });
    this.setState({
      tabList:tabList,
      tabListKeys:tabListKey,
      searchObj:searchObj
    });

  }
  remove = (targetKey) => {
    let { activeKey ,mainPath} = this.state;
    if(targetKey === mainPath ){
      message.warning('仅提供关闭首页外的其他标签页！');
    }else{
      let lastIndex,newActiveKey;
      const tabList = [], tabListKey = []
      this.state.tabList.forEach((pane, i) => {
        if (pane.key === targetKey) {
          lastIndex = i - 1;
        }else {
          tabList.push(pane)
          tabListKey.push(pane.key)
        }
      });
      if (lastIndex >= 0 && activeKey === targetKey) {
        newActiveKey = tabList[lastIndex].key;
      }else {
        newActiveKey = this.state.activeKey
      }
      const search = this.state.searchObj[newActiveKey] ? this.state.searchObj[newActiveKey] :''
      router.push(newActiveKey+search);
      this.setState({
        tabList:tabList,
        activeKey:newActiveKey,
        tabListKeys:tabListKey
      });
    }

  }

  getLayoutStyle = () => {
    const { fixSiderbar, isMobile, collapsed, layout } = this.props;
    if (fixSiderbar && layout !== 'topmenu' && !isMobile) {
      return {
        paddingLeft: collapsed ? '80px' : '256px',
      };
    }
    return null;
  };

  handleMenuCollapse = collapsed => {
    const { dispatch } = this.props;
    dispatch({
      type: 'global/changeLayoutCollapsed',
      payload: collapsed,
    });
  };

  renderSettingDrawer = () => {
    // Do not render SettingDrawer in production
    // unless it is deployed in preview.pro.ant.design as demo
    // preview.pro.ant.design only do not use in your production ; preview.pro.ant.design 专用环境变量，请不要在你的项目中使用它。
    if (
      process.env.NODE_ENV === 'production' &&
      ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION !== 'site'
    ) {
      return null;
    }
    return <SettingDrawer />;
  };
  onClickHover = (e) => {
    // message.info(`Click on item ${key}`);
    let { key } = e, { activeKey, tabList, tabListKey, routeKey } = this.state;
    if (key === '1') { //关闭当前标签页
      this.remove(activeKey);
    } else if (key === '2') {//关闭其他标签页
      this.removeOther();
    } else if (key === '3') {//关闭全部标签页
      this.removeAll();
    }
  }
  render() {
    const {
      navTheme,
      layout: PropsLayout,
      children,
      location: { pathname },
      user,
      isMobile,
      menuData,
      breadcrumbNameMap,
      fixedHeader,
      hidenAntTabs,
    } = this.props;

    const isTop = PropsLayout === 'topmenu';
    const contentStyle = !fixedHeader ? { paddingTop: 0 } : {};
    const menu = (
      <Menu onClick={this.onClickHover}>
        <Menu.Item key="1">关闭当前标签页</Menu.Item>
        <Menu.Item key="2">关闭其他标签页</Menu.Item>
        <Menu.Item key="3">关闭全部标签页</Menu.Item>
      </Menu>
    );
    const operations = (
      <Dropdown overlay={menu} >
        <a className="ant-dropdown-link" href="#">
          展开<Icon type="down" style={{ padding: '0 10px' }} />
        </a>
      </Dropdown>
    );
    const layout = (
      <Layout>
        <Header
          menuData={menuData}
          handleMenuCollapse={this.handleMenuCollapse}
          logo={platform_logo}
          title={title}
          isMobile={isMobile}
          {...this.props}
        />
        <Layout
          style={{
            ...this.getLayoutStyle(),
            minHeight: '100vh',
          }}
        >
        {isTop && !isMobile ? null : (
          <SiderMenu
            logo={platform_logo}
            theme={navTheme}
            onCollapse={this.handleMenuCollapse}
            menuData={menuData}
            isMobile={isMobile}
            title={title}
            {...this.props}
            //onHandlePage ={this.onHandlePage}
          />
        )}
          <Content className={styles.content} style={contentStyle}>
            {hidenAntTabs ?
              children
              :
              (this.state.tabList && this.state.tabList.length ? (
                <Tabs
                  className={styles.tabs}
                  activeKey={this.state.activeKey}
                  onChange={(key) =>
                  {
                    this.onChange(key)
                  }

                  }
                 tabBarExtraContent={operations}
                  tabBarStyle={{background:'#fff'}}
                  tabPosition="top"
                  tabBarGutter={-1}
                  hideAdd
                  type="editable-card"
                  onEdit={this.onEdit}
                >
                  {this.state.tabList.map(item => (
                    <TabPane tab={item.tab} key={item.key} closable={item.closable}>
                      <div>
                        <Route key={item.key} path={item.path} component={item.content} exact={item.exact} />
                      </div>
                    </TabPane>
                  ))}
                </Tabs>
              ) : null)}
          </Content>

        </Layout>
      </Layout>
    );
    return (
      <React.Fragment>
        <DocumentTitle title={getPageTitle(pathname, breadcrumbNameMap)}>
           {user.login_state === 'loading' ?
            <PageLoading/> :
            <ContainerQuery query={query}>
              {params => (
                <Context.Provider value={this.getContext()}>
                  <div className={classNames(params)}>{layout}</div>
                </Context.Provider>
              )}
            </ContainerQuery>
           }
        </DocumentTitle>
        {/*<Suspense fallback={null}>{this.renderSettingDrawer()}</Suspense>*/}
      </React.Fragment>
    );
  }
}

export default connect(({ global, setting, menu: menuModel ,user}) => ({
  collapsed: global.collapsed,
  layout: setting.layout,
  menuData: menuModel.menuData,
  breadcrumbNameMap: menuModel.breadcrumbNameMap,
  user,
  ...setting,
}))(props => (
  <Media query="(max-width: 599px)">
    {isMobile => <BasicLayout {...props} isMobile={isMobile} />}
  </Media>
));
